#ifndef FFTWALLOCATOR_H
#define FFTWALLOCATOR_H

#include <memory>
#include <vector>

#include <fftw3.h>

//TODO: FFTW3 default-double precision. Must be retrieved from fftw3.
typedef double fftw_double;

/**
* Template class FFTWAllocator allocates memory that aligned for CPU SIMD instructions.
* In general you can use it anywhere as STL compatible allocator.
* In the FFTPP library just use FFTWEngine::FFTWRealSignalPtr. For more details @see FFTWEngine
*/
template<class T>
class FFTWAllocator : public std::allocator<T>
{
public:
  typedef size_t	size_type;
  typedef ptrdiff_t	difference_type;
  typedef T*	pointer;
  typedef const T* const_pointer;
  typedef T&	reference;
  typedef const T& const_reference;
  typedef T	value_type;
    
  template<class U>
  inline pointer allocate(size_type n, const U *hint=0)
  {
      return reinterpret_cast<pointer>(fftw_malloc(sizeof(value_type)*n));
  };
            
  inline void deallocate(pointer p, size_type n)
  {
      fftw_free(p);
  };
};

/**
* The FFTWRealSignal is STL vector for fftw_double. This vector uses non-standard allocator.
* @see FFTWAllocator 
*/                      
typedef std::vector< fftw_double,FFTWAllocator<fftw_double> > FFTWRealSignal;

/**
* The FFTWComplexSignal is STL vector for fftw_complex. This vector uses non-standard allocator.
* @see FFTWAllocator 
*/
typedef std::vector< fftw_complex,FFTWAllocator<fftw_complex> > FFTWComplexSignal;
                      
#endif //FFTWALLOCATOR_H

